<template>
  <view :id="ridID" class="mxp-grid" :style="[gridStyle, cusStyle]">
    <slot v-if="isShow"></slot>
  </view>
</template>

<script lang="ts" setup>
  import { type CSSProperties, type PropType, computed, getCurrentInstance, onBeforeMount, onMounted, onUnmounted, provide, ref, watch } from 'vue';
  import { publicStyeProps } from '../mxp-tool/utils/public-props';
  import type { $AllSizeUnitStr, $SizeUnitStr } from '@/mxp-ui/mxp-tool/types/interface';
  import { getDomSize } from '../mxp-tool/utils/dom';
  import { getOnlyID } from '../mxp-tool/utils/common';
  import { type GridID, type MxpGridProps, gridInjectKey, mxpGridStore } from '../mxp-tool/store/mxp-store-grid';

  defineOptions({
    name: 'mxp-grid',
  });

  const props = defineProps({
    /** 整个宫格的宽度，注意：非 item 的宽度 */
    width: { type: String as PropType<$AllSizeUnitStr>, default: undefined },
    /** item的高度， 除了支持传入具体的尺寸外，还支持传入square代表正方形（即高度和宽度一致）， auto代表内容自适应高度，默认为 square */
    itemHeight: { type: String as PropType<$AllSizeUnitStr | 'auto' | 'square'>, default: 'square' },
    /** 分成几列 */
    col: { type: Number, default: 3 },
    /** 最后一排如果不够，时排列的方向 */
    align: { type: String as PropType<'center' | 'left' | 'right'>, default: 'left' },
    /** 每个 mxp-grid-item 的 左右间距 */
    xSpace: { type: String as PropType<$SizeUnitStr>, default: '0px' },
    /** 每个 mxp-grid-item 的 上下间距 */
    ySpace: { type: String as PropType<$SizeUnitStr>, default: '0px' },
    ...publicStyeProps,
  });
  defineSlots<{
    /** 主体内容 */
    default?: () => void;
  }>();
  /** 每个 mxp-grid-item 的 宽度 */
  const itemWidth = ref<$AllSizeUnitStr>('100px');

  const isShow = ref(false);
  const id: GridID = `__MXP-GRID-${getOnlyID('mxp-grid')}__`;
  const ridID = getOnlyID('mxp-grid');
  const instance = getCurrentInstance();
  const gridStyle = computed<CSSProperties>(() => {
    const style: CSSProperties = {};
    if (props.align === 'left') {
      style.justifyContent = 'flex-start';
    } else if (props.align === 'center') {
      style.justifyContent = 'center';
    } else {
      style.justifyContent = 'flex-end';
    }
    if (props.width) {
      style.width = props.width;
    }
    return style;
  });

  const gridStore = mxpGridStore();

  const gridProps = computed<MxpGridProps>(() => {
    const _gridProps: MxpGridProps = {
      col: props.col,
      itemHeight: props.itemHeight,
      itemWidth: itemWidth.value,
      xSpace: props.xSpace,
      ySpace: props.ySpace,
    };
    return _gridProps;
  });
  watch(
    () => gridProps.value,
    (val) => {
      gridStore.actions.setGridProps(id, val);
    }
  );
  gridStore.actions.setGridProps(id, gridProps.value);

  provide<GridID>(gridInjectKey, id);
  onBeforeMount(() => {
    provide<GridID>(gridInjectKey, id);
  });

  onUnmounted(() => {
    // 删除
    gridStore.actions.delItemByID(id);
  });

  onMounted(() => {
    setTimeout(async () => {
      const size = await getDomSize(`#${ridID}`, instance);
      itemWidth.value = `calc((${size.width}px - ${props.xSpace} * ${props.col - 1}) / ${props.col})`;
      isShow.value = true;
    }, 10);
  });
</script>

<style lang="scss" scoped>
  .mxp-grid {
    display: flex;
    flex: 1;
    flex-flow: row wrap;
    align-items: center;
    justify-content: center;
    width: 100%;
  }
</style>
